<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\common\model\Address;
use app\common\model\CityAgent;
use app\common\model\Comment;
use app\common\model\Coupon;
use app\common\model\CouponLog;
use app\common\model\DocumentType;
use app\common\model\Hospital;
use app\common\model\Notice;
use app\common\model\Service;
use app\common\model\Order as modelOrder;
use app\common\model\ServiceBasic;
use app\common\model\User;
use app\common\model\VipOrder;
use app\common\model\VipUser;
use app\common\model\WorkerInfo;
use app\common\service\Pay;
use think\facade\Db;
use think\Exception;
use think\facade\Config;
use think\facade\Validate;
use think\Model;

class Order extends Api
{
    protected $noNeedLogin = ['match','autoCancel','autoFinish','resetWorker','autoTransfer'];
    protected $noNeedRight = '*';


    public function documentType(){
        $list=DocumentType::order('weigh desc')->select()?:[];

        $this->success('成功',$list);
    }

    /**
     * 获取报价
     */
    public function price($is_api=true){
        $user=$this->auth->getUser();

        $code=request()->param('code');

        $self_care_ability=request()->param('self_care_ability');
        $days=request()->param('days');
        $hours=request()->param('hours');

        $coupon_id=request()->param('coupon_id');

        try {
            $service=ServiceBasic::alias('S')
                ->where(['code'=>$code])
                ->find()->toArray()?:[];

            ServiceBasic::realPrice($service,$user?$user['channel']:0);

            if(!$service)
                throw new Exception('未找到此服务信息');
            if($service['status']!='normal')
                throw new Exception('此服务已下架');

            if(in_array($code,['ward','special_ward','surgery_ward'])){
                if(!$days)
                    throw new Exception('请填写服务天数');
                if(!$self_care_ability)
                    throw new Exception('请选择自理能力');


                switch ($self_care_ability){
                    case 1:
                        if($service['day_price1']==0||$service['base_price']==0){
                            throw new Exception('暂未未设置此服务价格，请联系客服');
                        }
                        $price=bcadd(bcmul($days,$service['day_price1'],2),$service['base_price'],2);
                        break;
                    case 2:
                        if($service['day_price2']==0||$service['base_price']==0){
                            throw new Exception('暂未未设置此服务价格，请联系客服');
                        }
                        $price=bcadd(bcmul($days,$service['day_price2'],2),$service['base_price'],2);
                        break;
                    case 3:
                        if($service['day_price3']==0||$service['base_price']==0){
                            throw new Exception('暂未未设置此服务价格，请联系客服');
                        }
                        $price=bcadd(bcmul($days,$service['day_price3'],2),$service['base_price'],2);
                        break;
                    default:
                        throw new Exception('自理能力参数错误');
                }
            }
            else if($code=='escort_overtime'){
                if(!$hours)
                    throw new Exception('请填写服务时长');

                if($service['base_price']==0||$service['hour_price']==0){
                    throw new Exception('暂未未设置此服务价格，请联系客服');
                }

                $price=bcadd(bcmul($hours,$service['hour_price'],2),$service['base_price'],2);
            }
            else{
                if($service['base_price']==0){
                    throw new Exception('暂未未设置此服务价格，请联系客服');
                }
                $price=$service['base_price'];
            }
            /*if(in_array($service['code'],['escort','escort_vip','escort_halfday','escort_overtime'])){
                $price=$service['base_price'];
            }
            else{
                $price=$service['base_price'];
            }*/

            $last_price=$price;
            $vip_pay=0;
            $coupon=[];
            $coupon_price=0;
            $money_use=0;

            $check_vip=VipUser::where([['user_id','=',$user['id']],['status','=',1],['expire_time','>',time()]])->find()?:[];
            if($check_vip){
                if($check_vip[$code.'_last']>0){
                    $last_price=0;
                    $vip_pay=1;
                }
            }

            if(!$vip_pay){
                if($last_price>0){
                    if($coupon_id){
                        $coupon=CouponLog::with(['coupon'])->where(['id'=>$coupon_id,'user_id'=>$user['id']])->find()?:[];
                        if(!$coupon){$this->error('未找到此优惠券');}
                        if($coupon['use_time']&&$coupon['use_time']>0){$this->error('优惠券已被使用');}
                        if($coupon['expire_time']<=time()){$this->error('优惠券失效');}
                        if($coupon['expire_time']<=time()){$this->error('优惠券失效');}
                        if($coupon['coupon']['start_money']>$last_price){$this->error('订单金额未达到优惠券门槛金额');}
                    }
                    else if($coupon_id!==0&&$coupon_id!=='0'){
                        $coupon=$this->bestCoupon(false,$last_price);
                    }

                    if($coupon){
                        $coupon_price=$coupon['coupon']['discount_money'];
                        $last_price=bcsub($last_price,$coupon['coupon']['discount_money'],2);
                        if($last_price<0){
                            $last_price=0;
                        }
                    }
                }

                if($last_price>0&&$user['money']>0){
                    if($user['money']>=$last_price){
                        $last_price=0;
                        $money_use=$last_price;
                    }
                    else{
                        $last_price=bcsub($last_price,$user['money'],2);
                        $money_use=$user['money'];
                    }
                }
            }

        }catch (Exception $e){
            $this->error($e->getMessage());
        }

        $price_info=[
            'total_price'=>$price,
            'price'=>$last_price,
            'money_use'=>$money_use,
            'vip_pay'=>$vip_pay,
            'coupon'=>$coupon,
            'coupon_price'=>$coupon_price
        ];

        if($is_api){$this->success('成功',$price_info);}

        return $price_info;
    }


    /**
     * 按支付价格获取优惠券信息
     */
    public function bestCoupon($is_api=true,$price=0){
        if(!$price){
            $price=request()->param('price',0);
        }
        if(!$price&&$price!==0&&$price!=='0'){
            if($is_api)
                $this->error('金额错误');
            else
                throw new Exception('金额错误');
        }

        $user_id=$this->auth->getUser()['id'];

        $best_coupon=CouponLog::withJoin(['coupon'])
            ->where(['coupon_log.user_id'=>$user_id])
            ->where('coupon_log.expire_time','>',time())
            ->where('coupon.start_money','<=',$price)
            ->where('use_time','=',0)
            ->order('coupon.discount_money desc')
            ->select()?:[];

        /*$best_coupon=CouponLog::alias('CL')
            ->leftJoin('coupon C','C.id=CL.coupon_id')
            ->where(['CL.user_id'=>$user_id,['C.start_money','<=',$price]])
            ->field('CL.id,C.name,C.intro,C.start_money,C.discount_money,C.valid_time,C.create_time')
            ->order('discount_money desc')
            //->fetchsql()->select();
            ->select()->toArray()?:[];*/

        if(!$is_api){
            if($best_coupon)
                return $best_coupon[0];
            else
                return [];
        }

        $other_coupon=CouponLog::withJoin(['coupon'])
            ->where(['coupon_log.user_id'=>$user_id])
            ->where('coupon_log.expire_time','>',time())
            ->where('coupon.start_money','>',$price)
            ->where('use_time','=',0)
            ->order('coupon.discount_money desc')
            ->select()?:[];

        /*$other_coupon=CouponLog::alias('CL')
            ->leftJoin('coupon C','C.id=CL.coupon_id')
            ->where(['CL.user_id'=>$user_id,'C.start_money'=>['>',$price]])
            ->field('CL.id,C.name,C.intro,C.start_money,C.discount_money,C.valid_time,C.create_time')
            ->order('discount_money desc')
            ->select()->toArray()?:[];*/

        $this->success('成功',['usable'=>$best_coupon,'unusable'=>$other_coupon]);
    }

    /**
     * 创建订单
     */
    public function createOrder(){
        //$service_id=request()->param('service_id')?:0;

        $code=request()->param('code');
        $hospital_id=request()->param('hospital_id')?:0;

        $patient_id=request()->param('patient_id')?:0;
        $department_id=request()->param('department_id')?:0;
        $note=request()->param('note','');

        $document_type=request()->param('document_type')?:0;

        $address_id=request()->param('address_id')?:0;
        $medicine_name=request()->param('medicine_name','');
        $medicine_type=request()->param('medicine_type','');
        $prescription_img=request()->param('prescription_img','');

        $start_date=request()->param('start_date','');
        $days=request()->param('days','');
        $hours=request()->param('hours','');
        $bed_no=request()->param('bed_no','');
        $self_care_ability=request()->param('self_care_ability')?:0;

        $leave_time=request()->param('leave_time')?:null;
        $apply_reason=request()->param('apply_reason')?:0;
        $phone=request()->param('phone')?:'';

        $coupon_id=request()->param('coupon_id',0);
        $worker_id=request()->param('worker_id',0);

        $user=$this->auth->getUser();

        if(!$patient_id)
            $this->error("请选择就诊人");

        $basic_service=ServiceBasic::where(['code'=>$code])->find()?:[];
        if(!$basic_service)
            $this->error('未找到此项服务');
        if($basic_service['status']!='normal')
            $this->error('此项服务已停止服务');


        if(in_array($code,['ward','special_ward','surgery_ward','register','inquiry','escort','escort_vip','escort_halfday','escort_overtime','document','medicine','records'])){
            if(!$hospital_id){
                $this->error('请选择就诊医院');
            }
            $hospital=Hospital::get($hospital_id)?:[];
            if(!$hospital){
                $this->error('未找到此医院');
            }
            if(!$hospital['status']){
                $this->error('已停止此医院服务');
            }

            if(!$department_id&&$code!='medicine'){
                $this->error("请选择科室");
            }


            $service=Service::where(['basic_id'=>$basic_service['id'],'hospital_id'=>$hospital_id,'status'=>'normal'])->find()?:[];
            if(!$service)
                $this->error('此医院的该服务已停止');
            $basic_id=$service['basic_id'];
            $service_id=$service['id'];

            $start_time=strtotime($start_date);
            $end_date=$start_time+14*86400;


            if(!$start_date)
                $this->error("请选择开始时间");

            if($code=='ward'){
                if(!$bed_no)
                    $this->error('请填写住院床号');
                if(!$self_care_ability)
                    $this->error('请选择自理能力');
                if(!$days)
                    $this->error('请填写陪护天数');

                $end_date=$start_time+$days*86400;
            }
            /*计算陪诊类的有效时间*/
            if(in_array($code,['escort','escort_vip','escort_halfday','escort_overtime'])){

                if($code=='escort_halfday'){
                    $end_date=$start_time+4*3600;
                }
                else if(in_array($code,['escort','escort_vip'])){
                    $end_date=$start_time+12*3600;
                }
                else{
                    if(!$hours){
                        $this->error('请选择加时时长');
                    }
                    $end_date=$start_time+$hours*3600;
                }

            }


            if($code=='medicine'){
                if(!$address_id)
                    $this->error('请选择收货地址');
                if(!$medicine_name)
                    $this->error('请选择药品名称');
                if(!$medicine_type)
                    $this->error('请选择药品类型');
                if(!$prescription_img&&$medicine_type!='otc')
                    $this->error('请上传处方照片');
            }

            if($code=='records'){
                if(!$bed_no)
                    $this->error('请填写住院床号');
                if(!$leave_time)
                    $this->error('请填写出院时间');
                if(!$apply_reason)
                    $this->error('请选择病案用途');
                if(!$address_id)
                    $this->error('请选择收件地址');
            }


            if($code=='document'){
                if(!$address_id)
                    $this->error('请选择收件地址');
                if(!$document_type)
                    $this->error('请选择报告类型');
            }

            if($worker_id){
                $worker=WorkerInfo::get(['user_id'=>$worker_id])?:[];
                if(!$worker){
                    $this->error('没有找到此陪诊员信息');
                }
                if(in_array($code,['register','inquiry','escort','escort_vip','escort_halfday','escort_overtime','document','medicine','records'])&&$worker['pzy_status']!='normal'){
                    $this->error('此陪诊员不提供此种服务');
                }
                if(in_array($code,['ward','special_ward','surgery_ward'])&&$worker['phy_status']!='normal'){
                    $this->error('此陪诊员不提供此种服务');
                }
            }

        }
        elseif(in_array($code,['severe_illness','oversea','private_doctor','famous_doctor'])){
            $basic_id=$basic_service['id'];
            $service_id=0;

            if(!$phone){
                $this->error('请填写回访电话');
            }


            $end_date=time()+30*86400;
        }
        else{
            $this->error('未找到此项服务');
        }

        $price_info=$this->price(false);


        //计算收益
        $platform_money=$price_info['total_price'];

        if(!in_array($code,['severe_illness','oversea','private_doctor','famous_doctor'])){
            $worker_ratio=Config::get('site.worker_ratio');
            $worker_money=bcmul($price_info['total_price'],$worker_ratio/100,2);
            $platform_money=bcsub($platform_money,$worker_money,2);
        }
        else{
            $worker_money=0;
        }

        $inviter=[];
        $inviter_money=0;
        if($user['inviter_id']){
            $inviter=User::where(['id'=>$user['inviter_id'],'status'=>'normal'])->find()?:[];
            if($inviter){
                $inviter_ratio=Config::get('site.inviter_ratio');
                $inviter_money=bcmul($price_info['total_price'],$inviter_ratio/100,2);
                $platform_money=bcsub($platform_money,$inviter_money,2);
            }
        }

        $agent=[];
        $agent_money=0;
        if($hospital_id){
            $hospital=Hospital::get($hospital_id)?:[];
            if($hospital){
                $agent=CityAgent::where(['city'=>$hospital['city'],'status'=>'normal'])->find()?:[];
                if($agent){
                    $agent_ratio=Config::get('site.agent_ratio');
                    $agent_money=bcmul($price_info['total_price'],$agent_ratio/100,2);
                    $platform_money=bcsub($platform_money,$agent_money,2);
                }
            }
        }


        $order_sn=makePaySn($user['id']);

        Db::startTrans();
        try {

            $data=[
                'order_sn'=>$order_sn,
                'user_id'=>$user['id'],
                'worker_id'=>$worker_id,
                'service_id'=>$service_id,
                'hospital_id'=>$hospital_id,
                'service_basic_id'=>$basic_id,
                'patient_id'=>$patient_id,
                'department_id'=>$department_id,
                'document_type'=>$document_type,
                'note'=>$note,
                'address_id'=>$address_id,
                'medicine_name'=>$medicine_name,
                'medicine_type'=>$medicine_type,
                'prescription_img'=>$prescription_img,
                'begin_time'=>strtotime($start_date),
                'end_time'=>$end_date,
                'bed_no'=>$bed_no,
                'self_care_ability'=>$self_care_ability,
                'coupon_id'=>$coupon_id,
                'coupon_money'=>$price_info['coupon']?$price_info['coupon_price']:0,
                'worker_money'=>$worker_money,
                'platform_money'=>$platform_money,
                'inviter_id'=>$inviter?$inviter['id']:0,
                'inviter_money'=>$inviter?$inviter_money:0,
                'agent_id'=>$agent?$agent['user_id']:0,
                'agent_money'=>$agent?$agent_money:0,
                'total_price'=>$price_info['total_price'],
                'money_use'=>$price_info['money_use'],
                'pay_price'=>$price_info['price'],
                'create_time'=>time(),
                'code'=>$code,
                'leave_time'=>$leave_time?strtotime($leave_time):null,
                'apply_reason'=>$apply_reason,
                'phone'=>$phone,
                'status'=>1
            ];


            if($data['pay_price']==0){
                // 改变订单状态
                $data['pay_time'] = time();
                $data['status']   = 2;
            }

            $result= (new modelOrder)->insertGetId($data);


            if($price_info['vip_pay']){
                $vip_user=VipUser::where(['user_id'=>$user['id'],'status'=>1,])->order('id asc')->find()?:[];
                if(!$vip_user){
                    throw new Exception('未找到会员信息');
                }
                if($vip_user[$data['code'].'_last']<=0){
                    throw new Exception('该类型服务的免单次数已用尽');
                }
                $vip_user[$data['code'].'_last']-=1;
                $vip_user->save();

                $vip_order=VipOrder::where(['vip_user_id'=>$vip_user['id'],'user_id'=>$user['id'],'code'=>$data['code'],'status'=>0])->order('id asc')->find()?:[];
                if(!$vip_order){
                    throw new Exception('无可用的免单次数');
                }
                $vip_order['order_id']=$result;
                $vip_order['status']=1;
                $vip_order['use_time']=$data['create_time'];
                $vip_order->save();
            }


            if($price_info['money_use']){
                User::money(-1*$price_info['money_use'],$user['id'],'下单余额自动抵扣');
            }

            if($price_info['coupon']){
                $price_info['coupon']['use_time']=time();
                $price_info['coupon']->save();
            }
        }
        catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }
        Db::commit();
        $this->success('成功',['id'=>$result,'order_sn' => $order_sn,'paid'=>$data['status']==2?1:0]);
    }

    /**
     * 自动匹配
     */
    public function match(){
        $orders=modelOrder::where(['status'=>2,'parent_id'=>0])->select()?:[];
        $counter=0;
        $WI=new WorkerInfo();
        $U=new User();
        foreach ($orders as &$o){
            /*Db::startTrans();
            try {*/
                $transfer_arr=$o['transfer_arr']?json_decode($o['transfer_arr']):[];

                $hospital=Hospital::get($o['hospital_id'])?:[];
                if(!$hospital)
                    continue;

//                $where=[
//                    'U.status'=>'normal',
//                    'U.is_spare'=>1,
//                    'U.working_status'=>1,
//                    'WF.city'=>$hospital['city']
//                ];
//
//
//                if($o['code']=='ward')
//                    $where['WF.phy_status']=1;
//                else
//                    $where['WF.pzy_status']=0;
//
//                $best_match= $WI->alias('WF')
//                    ->leftJoin('user U','WF.user_id=U.id')
//                    ->where($where)
//                    ->whereNotIn('U.id',$transfer_arr)
//                    ->field('U.*,WF.city')
//                    ->order('worker_score desc')
//                    ->find();


                $where=[
                    'U.status'=>'normal',
                //    'U.is_spare'=>1,
                    'U.working_status'=>1,
                    'WF.city'=>$hospital['city'],
                ];


                if(in_array($o['code'],['ward','special_ward','surgery_ward']))
                    $where['WF.phy_status']='normal';
                else
                    $where['WF.pzy_status']='normal';

                $worker_list= $WI->alias('WF')
                    ->leftJoin('user U','WF.user_id=U.id')
                    ->leftJoin(" (select worker_id,count(id) counter from fa_order where status in (3,4,5,15) and worker_id<>0 and parent_id=0 group by worker_id) S1","S1.worker_id=WF.user_id")
                    ->where($where)
                    ->where('WF.id_no','<>','')
                    ->where('WF.id_card_front','<>','')
                    ->where('WF.id_card_back','<>','')
                    ->where('WF.hold_id_card','<>','')
                //    ->where('U.id','<>',$o['user_id'])
                    ->whereNotIn('U.id',$transfer_arr)
                    ->where("S1.counter < 5 or S1.counter is null")
                    ->field('U.*,WF.city,counter')
                    ->order('worker_score desc,S1.counter asc')
                    ->select()->toArray()?:[];


                $begin_time=$o['begin_time'];
                $end_time=$o['end_time']?:$begin_time+43200;

                $best_match=false;
                foreach ($worker_list as $wl){
                    $check_order=modelOrder::where([
                        ['worker_id','=',$wl['id']],
                        ['status','in',[3,4,5,15]],
                        ['begin_time','<',$end_time],
                        ['end_time','>',$begin_time]
                    ])
                        ->select()->toArray()?:[];
                    if(!$check_order){
                        $best_match=$wl;
                        break;
                    }
                }

                if($best_match){
                    $transfer_arr[]=$best_match['id'];

                    $o['transfer_arr']=json_encode($transfer_arr);
                    $o['worker_id']=$best_match['id'];
                    $o['match_time']=time();
                    $o['status']=3;
                    $o->save();

                    //$U->spare($best_match['id'],0);
                    Notice::create([
                        'title'=>'派单提醒',
                        'content'=>'您有一个新的订单，请及时处理。',
                        'type'=>2,
                        'user_id'=>$o['worker_id'],
                        'order_id'=>$o['id']
                    ]);
                    $counter++;
                }
            /*    Db::commit();
            }catch (Exception $e){
                Db::rollback();
                echo($e->getMessage()).'\n\r';
            }*/
        }
        echo '共'.count($orders).'个订单需要匹配。此轮已匹配'.$counter.'个订单';
    }

    /**
     * 发送订单提醒短信、自动转单、取消多次转单订单
     */
    public function autoTransfer(){
        $accept_notice_time=Config::get('site.accept_notice_time');
        $max_transfer=Config::get('site.max_transfer');

        $U=new User();
        //发送接单提醒短信
        $ids=[];
        $list=modelOrder::where([
            ['sms_accept_notice','=',0],
            ['status','=',3],
            ['match_time','<=',time()-$accept_notice_time*60]
        ])->select()?:[];

        foreach($list as &$l){
            $ids[]=$l['id'];
            $worker=$U::get($l['worker_id'])?:[];
            //if(!$worker||!$worker['mobile']){
            if(!$worker){
                $l['sms_accept_notice']=2;
                $l->save();
                continue;
            }
            /*if($worker['type']=='1')
                $string='陪护员';
            else
                $string='陪诊员';*/

            $mobile_phone=Config::get('site.mobile_phone');
            if($mobile_phone||Validate::regex($mobile_phone, "^1\d{10}$")){
                \app\common\model\Sms::SendSms("{$l['id']},{$accept_notice_time}",$mobile_phone,0,616392);

                $l['sms_accept_notice']=1;
            }
            else{
                $l['sms_accept_notice']=2;
            }

            $l->save();
        }


        //双倍时间后,处理需转单的订单
        $transfer_list=modelOrder::where([
            ['sms_accept_notice','in',[1,2]],
            ['status','=',3],
            ['match_time','<=',time()-$accept_notice_time*60*2],
            ['id','not in',$ids?:[0]]
        ])->select()?:[];
        foreach ($transfer_list as &$tl){
            //若达到最大转单次数，则取消订单
            $transfer_arr=json_decode($tl['transfer_arr']);
            if(count($transfer_arr)>$max_transfer){
                if($l['pay_price']>0)
                    Pay::refund($tl,'取消订单返还金额');

                if($tl['coupon_id'])
                    CouponLog::update(['use_time'=>0],['id'=>$tl['coupon_id']]);
                $tl['status']=10;
                $tl['cancel_time']=time();
                $tl['cancel_reason']='到达最大转单次数，无陪诊员接单，自动取消订单。';
                $tl->save();

                //$U->spare($tl['worker_id']);
                continue;
            }

            //自动转单
            $tl['status']=2;
            $tl['worker_id']=0;
            $tl['transfer_time']=time();
            $tl['transfer_reason']='陪诊员长时间未处理订单，自动转单。';
            $tl['sms_accept_notice']=0;
            $tl['match_time']=null;
            $tl->save();
            //$U->spare($tl['worker_id']);
        }

    }

    /**
     * 自动取消
     */
    public function autoCancel(){
        $pay_time_limit=config('site.pay_time_limit')?:0;
        //未支付自动取消
        if($pay_time_limit){
            $time=time()-$pay_time_limit*60;
            $order=modelOrder::where([['status','=',1],['create_time','<',$time]])->select();
            foreach ($order as &$o){
                $o['status']=11;
                $o['cancel_time']=time();
                $o->save();

                if($o['worker_id'])
                    //(new User)->spare($o['worker_id']);

                if($o['coupon_id'])
                    CouponLog::update(['use_time'=>0],['id'=>$o['coupon_id']]);

                if($o['vip_pay'])
                    Viporder::update(['use_time'=>null],['order_id'=>$o['id']]);


                Notice::create([
                    'title'=>'订单自动取消提醒',
                    'content'=>"您的一个订单在40分钟内未支付，已被自动取消。",
                    'type'=>2,
                    'user_id'=>$o['user_id'],
                    'order_id'=>$o['id'],
                    'create_time'=>time()
                ]);
            }
        }

        //已支付、未匹配订单自动取消
        /*$accept_notice_time=Config::get('site.accept_notice_time')?:0;
        if($accept_notice_time<=0)
            $accept_notice_time=10;
        $paid_order=modelOrder::where([['status','=',2],['create_time','<',$time]])->select()?:[];

        foreach ($paid_order as &$po){
            if($po['pay_price']>0)
                Pay::refund($po,'取消订单返还金额');

            if($po['coupon_id'])
                CouponLog::update(['use_time'=>0],['id'=>$po['coupon_id']]);
            $po['status']=10;
            $po['cancel_time']=time();
            $po['cancel_reason']='无可匹配的陪诊员，自动取消订单。';
            $po->save();
        }*/
    }

    /**
     * 自动完成订单
     */
    public function autoFinish(){
        $time=time()-3600;

        $list=modelOrder::where([
                ['code','in',['ward','special_ward','surgery_ward','register','inquiry','escort','escort_vip','escort_halfday','escort_overtime','document','medicine','records']],
                ['status','=',5],
                ['end_time','<=',$time]
            ])
            ->select()?:[];
        foreach ($list as &$l){
            $l['finish_time']=time();
            $l['status']=6;
            $l->save();
            //(new User)->spare($l['worker_id']);
        }
    }

    /**
     * 重置接单状态
     */
    public function resetWorker(){
        $user_id=request()->param('user_id');

        $user=User::get($user_id)?:[];
        if(!$user)
            $this->error('未找到该用户');

        $user['is_spare']=1;
        $user->save();

        $this->success('成功');
    }

    /**
     * 订单列表
     */
    public function list(){
        $user       = $this->auth->getUser();
        $type       = request()->param('type',false);
        $page       = request()->param('page',1);
        $is_worker  = request()->param('is_worker',0);

        $where = [
            'parent_id'=>0
        ];

        /*if ($is_worker == 1) {
            $worker_id=User::getWorkerId($user['id']);
            if(!$worker_id)
                $this->error('技师信息错误');
            $where['worker_id'] = $user['id'];
        }*/

        if($is_worker!=1)
            $where['order.user_id'] = $user['id'];
        else
            $where['order.worker_id'] = $user['id'];

        if(!in_array($type,['all','unpaid','working','finished','canceled','new','accepted','transferred','unevaluate','evaluated','takeable']))
            $this->error('类型参数不正确');

        $O=ModelOrder::with(['user','patient','servicebasic','hospital']);


        if($type=='unpaid')
            $where['order.status']=[11];
        if($type=='working')
            $where['order.status']=[5,15];
        if($type=='finished')
            $where['order.status']=[6,7,41,42,43];
        if($type=='canceled')
            $where['order.status']=[10,11];
        /*if($type=='withdraw')
            $where['order.status']=[41,42,43];*/

        if($type=='new')
            $where['order.status']=[2,3,4,15];
        if($type=='accepted')
            $where['order.status']=4;
        if($type=='transferred'){
            //$where['transfer_arr']=['like',"%'{$user['id']}'%"];
            $O->whereLike('transfer_arr',"%'{$user['id']}'%");
            unset($where['order.worker_id']);
            $O->where('worker_id','<>',$user['id']);
        }
        if($type=='unevaluate'){
            $where['order.status']=[6,7,41,42,43];
            $where['order.worker_commented']=0;
        }
        if($type=='evaluated'){
            $where['order.status']=[6,7,41,42,43];
            $where['order.worker_commented']=1;
        }

        if($type=='takeable'){
            $where['order.status']=2;
            unset($where['order.worker_id']);
            $worker_info=WorkerInfo::get(['user_id'=>$user['id']]);
            if($worker_info){
                $where['hospital.city']=$worker_info['city'];
            }

            $code_arr=[];

            if($user['pzy_status']=='normal'){
                $code_arr=array_merge($code_arr,['register','inquiry','escort','escort_vip','escort_halfday','escort_overtime','document','medicine','records']);
            }
            if($user['phy_status']=='normal'){
                $code_arr=array_merge($code_arr,['ward','special_ward','surgery_ward']);
            }


            $order=$O->withJoin(['hospital'])
                ->with(['patient','servicebasic'])
                //->leftjoin('fa_hospital H','O.hospital_id=H.id')
                ->where($where)
            //    ->where('order.user_id','<>',$user['id'])
                ->where('order.code','in',$code_arr)
                ->order('order.create_time desc')
                //->field('O.*')
                ->page($page,20)
                ->select()?:[];

        }
        else{
            //$order=ModelOrder::with(['user','patient','servicebasic','hospital'])
            //->field('order.*,user.danger_level')
            $order=$O->withJoin(['hospital'])
                ->with(['patient','servicebasic'])
                ->where($where)
                ->order('order.create_time desc')
                ->page($page,20)
                ->select()?:[];
        }

        foreach ($order as $o){
            $o->visible([
                'user'=>['avatar','username'],
                'patient'=>['name'],
                'servicebasic'=>['code','name'],
                'hospital'=>['name','thumb']
            ])->toArray();

            $o::fetchCompleteStatus($o,$is_worker);
        }

        $this->success('请求成功',$order);
    }

    /**
     * 订单详情
     */
    public function detail(){
        $order_id=request()->param('order_id');
        $is_worker  = request()->param('is_worker',0);

        $order=ModelOrder::with([
            'user',
            'patient',
            'worker'=>function($query){
                $query->with(['workerInfo']);
            },
            'servicebasic',
            'hospital',
            'department',
            'address'
        ])
            //->field('order.*,user.danger_level')
            ->where(['id'=>$order_id])->find()?:[];

        if(!$order){
            $this->error('未找到此订单信息');
        }

        $order->visible([
            'user'=>['avatar','gender','score','mobile'],
            'patient'=>['name','mobile','id_no'],
            'worker'=>['id','worker_score','avatar','workerInfo.name','workerInfo.mobile','workerInfo.gender','workerInfo.age'],
            'servicebasic'=>['code','name'],
            'hospital'=>['name'],
            'department'=>['name'],
            'address'=>'*',
        ])->toArray();

        ModelOrder::fetchCompleteStatus($order,$is_worker);

        $order['user_comment']=Comment::get(['order_id'=>$order_id,'type'=>1])?:[];
        $order['worker_comment']=Comment::get(['order_id'=>$order_id,'type'=>0])?:[];

        $this->success('请求成功',$order);

    }

    /**
     * 取消订单
     */
    public function cancel(){
        $user=$this->auth->getUser();

        $order_id=request()->param('order_id');
        $reason=request()->param('reason');

        $order=modelOrder::get($order_id)?:[];
        if(!$order)
            $this->error('未找到订单信息');
        if($order['user_id']!=$user['id'])
            $this->error('非下单用户，不可取消订单');
        if(!in_array($order['status'],[1,2,3,4]))
            $this->error('当前订单状态不可取消订单');

        if(!$reason)
            $this->error('请填写取消原因');

        if($order['pay_time']) {
            $money_return=$order['money_use'];
            $pay_return=$order['pay_price'];
            $cancel_fine=Config::get('site.cancel_fine');
            if((($order['begin_time']<time()+10800)||$order['status']==5)&&$cancel_fine>0){
                if($money_return>=$cancel_fine){
                    $money_return=bcsub($money_return,$cancel_fine,2);
                    $cancel_fine=0;
                }
                else{
                    $cancel_fine=bcsub($cancel_fine,$money_return,2);
                    $money_return=0;
                }

                if($pay_return>=$cancel_fine){
                    $pay_return=bcsub($pay_return,$cancel_fine,2);
                    $cancel_fine=0;
                }
                else{
                    $pay_return=0;
                }

                Notice::create([
                    'title'=>'订单取消',
                    'content'=>"您已取消一笔订单，由于此订单将于3小时内开始服务，取消时将会扣除$cancel_fine 元费用",
                    'type'=>2,
                    'user_id'=>$order['user_id'],
                    'order_id'=>$order['id'],
                    'create_time'=>time()
                ]);
            }
            if($money_return>0){
                User::Money($money_return,$order['user_id'],'取消订单返还余额');
            }
            if($pay_return>0){
                Pay::refund($order,'取消订单返还金额',$pay_return);
            }

            if($order['vip_pay'])
                Viporder::update(['use_time'=>null],['order_id'=>$order['id']]);
        }

        if($order['coupon_id'])
            CouponLog::update(['use_time'=>0],['id'=>$order['coupon_id']]);

        $order['status']=10;
        $order['cancel_time']=time();
        $order['cancel_reason']=$reason;
        $order->save();

        /*if($order['worker_id'])
            (new User)->spare($order['worker_id']);*/

        $this->success('成功');
    }

    /**
     * 转单
     */
    public function transfer(){
        $user=$this->auth->getUser();

        $order_id=request()->param('order_id');
        //$reason=request()->param('reason','');

        $order=modelOrder::get($order_id)?:[];
        if(!$order)
            $this->error('未找到订单信息');
        if(!in_array($order['status'],[3,4]))
            $this->error('当前订单状态不可转单');

        /*if(!$reason)
            $this->error('请填写转单原因');*/

        $check= (new modelOrder)->checkWorker($user,$order);
        if($check!==true)
            $this->error($check);

        $order['status']=3;
        $order['transfer_time']=time();
        //$order['transfer_reason']=$reason;
        $order->save();

        $this->success('成功');
    }

    /**
     * 接单
     */
    public function take(){
        $user=$this->auth->getUser();

        $order_id=request()->param('order_id');

        $order=modelOrder::get($order_id)?:[];
        if(!$order)
            $this->error('未找到订单信息');
        /*if($order['user_id']==$user['id'])
            $this->error('不可接受自己的订单');*/
        if($order['status']!=2)
            $this->error('当前订单状态不可进行抢单');


        $check= (new modelOrder)->checkWorker($user,$order);
        if($check!==true)
            $this->error($check);

        $transfer_arr=json_decode($order['transfer_arr'])?:[];
        $transfer_arr[]=$user['id'];

        $order['status']=4;
        $order['accept_time']=time();

        $order['transfer_arr']=json_encode($transfer_arr);
        $order['worker_id']=$user['id'];
        $order->save();


        $this->success('成功');
    }

    /**
     * 接单
     */
    public function accept(){
        $user=$this->auth->getUser();

        $order_id=request()->param('order_id');

        $order=modelOrder::get($order_id)?:[];
        if(!$order)
            $this->error('未找到订单信息');
        if($order['status']!=3)
            $this->error('当前订单状态不可进行接单');

        $check= (new modelOrder)->checkWorker($user,$order);
        if($check!==true)
            $this->error($check);

        $order['status']=4;
        $order['accept_time']=time();
        $order->save();


        $this->success('成功');
    }

    /**
     * 出发
     */
    public function start(){
        $user=$this->auth->getUser();

        $order_id=request()->param('order_id');
        $lon=request()->param('lon');
        $lat=request()->param('lat');
        if(!$lon||!$lat||$lon=='undefined'||$lat=='undefined'||$lon=='null'||$lat=='null')
            $this->error('定位信息错误');

        $order=modelOrder::get($order_id)?:[];
        if(!$order)
            $this->error('未找到订单信息');
        if($order['status']!=4)
            $this->error('当前订单状态不可进行接单');

        $check= (new modelOrder)->checkWorker($user,$order);
        if($check!==true)
            $this->error($check);

        $order['status']=5;
        $order['start_time']=time();
        $order['start_lon']=$lon;
        $order['start_lat']=$lat;
        $order->save();


        $this->success('成功');
    }


    /**
     * 完成订单
     */
    public function finish(){
        $user=$this->auth->getUser();
        $order_id=request()->param('order_id',0);

        $order=modelOrder::get($order_id)?:[];
        if(!$order)
            $this->error('未找到订单信息');

        if($user['id']!=$order['user_id'])
            $this->error('非下单用户本人，不能结束订单');
        /*if(in_array($order['code'],['ward','escort','escort_vip','escort_halfday'])){
            if($user['id']!=$order['user_id'])
                $this->error('非下单用户本人，不能结束订单');
        }
        else{
            if($user['id']!=$order['worker_id'])
                $this->error('非陪诊员本人，不能结束订单');

            $user=User::get($order['user_id']);
        }*/

        if($order['status']!=5)
            $this->error('当前订单状态不可完成订单');


        Db::startTrans();
        try {

            $order['finish_time']=time();
            $order['status']=6;
            $order->save();


            //(new User)->spare($order['worker_id']);

            Db::commit();
        }catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }

        $this->success('成功');

    }

    public function comment(){
        $user=$this->auth->getUser();
        $order_id=request()->param('order_id');
        $is_worker=request()->param('is_worker');
        $content=request()->param('content');
        $score=request()->param('score');

        $order=modelOrder::get($order_id)?:[];
        if(!$order)
            $this->error('未找到订单信息');

        if(!in_array($order['status'],[6,7]))
            $this->error('订单状态目前不可评价');
        if($user['id']!=$order['user_id']&&!$is_worker)
            $this->error('非订单用户本人，不可进行评价');

        /*if($user['id']!=$order['worker_id']&&$is_worker)
            $this->error('非陪诊员本人，不可进行评价');*/

        if(!$is_worker){
            if($order['patient_commented'])
                $this->error('已评价过此订单，请勿重复提交');
            $data=[
                'user_id'=>$user['id'],
                'target_id'=>$order['worker_id'],
                'order_id'=>$order['id'],
                'type'=>0,
                'content'=>$content,
                'score'=>$score,
                'create_time'=>time()
            ];
            $order['patient_commented']=1;
            Comment::insert($data);
            $score=Comment::where(['type'=>0,'target_id'=>$order['worker_id']])->group('target_id')->avg('score');
            User::update(['worker_score'=>$score],['id'=>$order['worker_id']]);
        }

        /*if($is_worker){
            if($order['worker_commented'])
                $this->error('已评价过此订单，请勿重复提交');
            $data=[
                'user_id'=>$user['id'],
                'target_id'=>$order['user_id'],
                'order_id'=>$order['id'],
                'type'=>1,
                'content'=>$content,
                'score'=>$score
            ];
            $order['worker_commented']=1;
            Comment::insert($data);
            $score=Comment::where(['type'=>1,'target_id'=>$order['user_id']])->group('target_id')->avg('score');
            User::update(['score'=>$score],['id'=>$order['user_id']]);
        }


        if($order['patient_commented']&&$order['worker_commented'])
            $order['status']=7;*/
        $order->save();
        $this->success('成功');

    }

    public function escortEndTime(){
        $start_date=request()->param('start_date');
        if(!$start_date)
            $this->error('请选择开始时间');

        $end_date=date('Y-m-d H:i:s',strtotime($start_date)+4*3600);
        $this->success('成功',$end_date);
    }

    /**
     * 获取最新未接单订单
     */
    public function newOrder(){
        $user=$this->auth->getUser();

        $last_create_time=request()->param('last_create_time')?:0;


        $list=modelOrder::with(['user','patient','servicebasic','hospital'])
            ->where(['worker_id'=>$user['id'],'status'=>3])
            ->where('create_time','>',$last_create_time)
            ->order('create_time desc')
            ->select()?:[];

        $num=modelOrder::where(['worker_id'=>$user['id'],'status'=>3])
            ->count()?:0;

        foreach ($list as $o){
            $o->visible([
                'user'=>['avatar'],
                'patient'=>['name'],
                'servicebasic'=>['code','name'],
                'hospital'=>['name','thumb']
            ])->toArray();
        }

        $voice=Config::get('site.new_order_mp3')?:'';

        $this->success('成功',['list'=>$list,'voice'=>$voice,'num'=>count($list),'total'=>$num]);
    }
}

